//#include <rclcpp/async_parameters_client.hpp>
#include <chrono>
#include <rclcpp/rclcpp.hpp>

using namespace std::chrono_literals;

class ExampleNode : public rclcpp::Node {
public:
  ExampleNode() : Node("example_node") {
    // 1. 创建异步参数客户端（目标节点名：target_node）
    parameters_client_ = std::make_shared<rclcpp::AsyncParametersClient>(
        this,         // 当前节点接口
        "target_node" // 目标节点名称
    );

    // 2. 等待目标节点的参数服务可用
    while (!parameters_client_->wait_for_service(1s)) {
      if (!rclcpp::ok()) {
        RCLCPP_ERROR(this->get_logger(),
                     "Interrupted while waiting for the service. Exiting.");
        rclcpp::shutdown();
      }
      RCLCPP_INFO(this->get_logger(),
                  "service not available, waiting again...");
    }

    get_param();
    rclcpp::sleep_for(1s);
    set_param();
    rclcpp::sleep_for(1s);
    get_param_callback();
  }

  void get_param() {
    // 3. 异步获取参数 "max_speed"
    auto future = parameters_client_->get_parameters({"max_speed"});

    // 4.
    RCLCPP_INFO(get_logger(), "正在获取目标节点参数...");
    // 等待结果
    if (rclcpp::spin_until_future_complete(this->get_node_base_interface(),
                                           future) !=
        rclcpp::FutureReturnCode::SUCCESS) {
      RCLCPP_ERROR(get_logger(), "获取参数服务调用失败");
      return;
    }
    // 只有单一进程，如果future.get导致进程阻塞，就会导致进程无法相应其他请求;
    // 比如ctrl+c退不出程序。
    RCLCPP_INFO(get_logger(), "目标节点参数：%f",
                future.get().at(0).as_double());
    RCLCPP_INFO(get_logger(), "获取参数成功！");
  }

  void get_param_callback() {
    // 3. 异步获取参数 "max_speed"
    auto future =
        parameters_client_->get_parameters({"max_speed"}, [this](auto future) {
          RCLCPP_INFO(get_logger(), "目标节点参数：%f",
                      future.get().at(0).as_double());
          RCLCPP_INFO(get_logger(), "获取参数成功！");
        });
  }

  void set_param() {
    // 5. 异步设置参数 "max_speed"
    auto future = parameters_client_->set_parameters(
        {{"max_speed", 10.0}}, [this]([[maybe_unused]] auto future) {
          // 6.
          // RCLCPP_INFO(get_logger(), "正在设置目标节点参数...");
          // 等待结果
          // if
          // (rclcpp::spin_until_future_complete(this->get_node_base_interface(),
          //                                        future) !=
          //     rclcpp::FutureReturnCode::SUCCESS) {
          //   RCLCPP_ERROR(get_logger(), "设置参数服务调用失败");
          //   return;
          // }
          RCLCPP_INFO(get_logger(), "设置参数成功！");
        });
  }

private:
  rclcpp::AsyncParametersClient::SharedPtr parameters_client_;
};

int main(int argc, char **argv) {
  rclcpp::init(argc, argv);
  auto node = std::make_shared<ExampleNode>();
  rclcpp::spin(node);
  rclcpp::shutdown();
  return 0;
}